我們在介紹程式流程時,有簡單帶過 app.module.ts
。在 Angular 裡,module 是一個不可或缺的元素,我們可以把多個相近的功能,包成一個 module,這樣在功能劃分及管理上,會比較乾淨。
下命令建立 module:
ng generate module <module name>
或是:
ng g m <module name>
一個 ngModule 總共有這些參數:
export declare interface NgModule {
providers?: Provider[];
declarations?: Array<Type<any> | any[]>;
imports?: Array<Type<any> | ModuleWithProviders<{}> | any[]>;
exports?: Array<Type<any> | any[]>;
entryComponents?: Array<Type<any> | any[]>;
bootstrap?: Array<Type<any> | any[]>;
schemas?: Array<SchemaMetadata | any[]>;
id?: string;
jit?: true;
}
providers
這邊可以放進共用的 service
,讓這個 Module 底下的所有元件都可以使用,通常我們會為了降低元件的相依性,而將一些功能做成 service
,之後會再介紹。
declarations
如之前介紹,這邊放入 Component
、Pipe
、Directive
。一旦這個 Component
、Pipe
、Directive
被放進一個 Module 的 declarations
,那麼這個元件,就不能放到其他Module的 declarations
中,否則編譯器會報錯。這種情況必須透過 imports
、exports
做使用。
imports
要使用到其他 Module 的 Component
、Pipe
、Directive
,就將那個 Module
放在 imports
中,比如說我們之前用的 ngModel
,就必須將 FormsModule
加入 imports
。
exports
如果要讓其他 Module,使用我放在 declarations
的 Component
、Pipe
、Directive
,就可以在這裡宣告該元件的 class 名稱,將這個 class 匯出。
entryComponents
假設我有一個元件,在程式時一開始並沒有放在 template
中被使用,而是在執行期時動態加入,就必須將該元件也放進這個欄位。否則一開始沒有使用到的元件, Angular 就不會編譯,就會報錯。
bootstrap
放入啟動的 Component
,只有 root module 需要設定。
schemas
如果使用了自訂的HTML,或這個元素不是在HTML標準裡的話,若Angular 無法解讀,那麼就會報錯,此時可以透過設定這個欄位來解決,請參考 保哥的文章。不過這個欄位很少使用,目前筆者還沒遇到需要設定的情況。
id
可以為 module設定一個識別用的名字,只有在 getModuleFactory()
時會用到,很少使用,通常不需設定。
jit
使用 JIT (Just-In-Time)編譯,而非 AOT(Ahead-of-Time),通常不需設定。
差別在於,瀏覽網頁時,JIT 是將程式碼下載到本地在進行編譯,而 AOT 是在 server 將程式碼編譯完後再下載到本地執行。
我們剛剛已經創建了一個全新的 module
,我這裡命名為 account
,並且會自動放進 account
資料夾:
一個 module 我們會希望包含至少這幾個元素:
@NgModule({
declarations: [],
providers: [],
imports: [],
exports: [],
...
})
我希望先做一個簡單的登入功能,並給其他 module 使用。
我先移動到 /account 底下,這樣建立元件時,就會自動被放進 account
這個 module 裡面:
cd .\src\
cd .\app\
cd .\account\
ng g c login
像這樣:
我們在 LoginComponent
建立一個簡單的 form
,
// login.component.html
<form>
帳號 <input type="text"><br>
密碼 <input type="password"><br>
<input type="submit" value="Login">
</form>
然後要記得在 account.module.ts
的 exports
加入 LoginComponent
,匯出我們剛剛的 LoginComponent
。
@NgModule({
declarations: [LoginComponent],
imports: [
CommonModule
],
exports: [LoginComponent],
providers: []
})
export class AccountModule { }
在 AppModule
中匯入剛剛建立的 AccountModule
:
接著我將 <app-login></app-login>
加到 homepage.component.html
我們就能在其他 module 使用 login 這個元件了。